﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using UnisysMassiveImporter_v2.Entidades.Documentos;
using UnisysMassiveImporter_v2.Entidades.Mensajes;
using System.Collections;
using System.Xml;
using UnisysMassiveImporter_v2.Negocio.InfoImage;
using UnisysMassiveImporter_v2.Entidades.Configuracion;

namespace UnisysMassiveImporter_v2.Datos.Archivos
{
    public class Files
    {
       

        //devuelven documents solo con su filePath y su length
        #region Obtener DATA

        public ArrayList getDataPreview1(ref Configuration appConfig, ref Thread_Config threadConfig)
        {
            ArrayList expedientes = new ArrayList();
            InfoMessage message = new InfoMessage();


            message.sendMessage("Iniciando la creacion del data previewList", InfoMessage.Information_Message, 573,threadConfig.Name,ref appConfig);
            message.sendMessage("Buscando archivos DATA en la carpeta: " + threadConfig.DataPath, InfoMessage.Information_Message, 574, threadConfig.Name, ref appConfig);
            try
            {
                foreach (String dayPath in System.IO.Directory.GetDirectories(threadConfig.DataPath))
                {
                    DirectoryInfo dir = new DirectoryInfo(dayPath + "\\Data");
                    foreach (FileInfo file in dir.GetFiles())//se buscan archivos dentro de la carpeta data
                        switch (threadConfig.Filetype)
                        {
                            case 1:
                                {
                                    message.sendMessage("Buscando Archivos .XML en la carpeta: " + dir.FullName, InfoMessage.Information_Message, 575, threadConfig.Name, ref appConfig);
                                    if (file.Extension.ToLower().Equals(".xml"))
                                    {
                                        message.sendMessage("Archivo Encontrado: " + file.FullName, InfoMessage.Success_Message, 273, threadConfig.Name, ref appConfig);
                                        Document doc = new Document(); 
                                        doc.filePath= file.FullName;
                                        doc.length=file.Length;
                                        expedientes.Add(doc);
                                        message.sendMessage("Se agrego el archivo a la lista el archivo: " + file.FullName, InfoMessage.Information_Message, 576, threadConfig.Name, ref appConfig);                                        
                                    }
                                } break;

                            case 2:
                                {
                                    message.sendMessage("Buscando Archivos .CSV en la carpeta: " + dir.FullName, InfoMessage.Information_Message, 575, threadConfig.Name, ref appConfig);
                                    if (file.Extension.ToLower().Equals(".csv"))
                                    {
                                        message.sendMessage("Archivo Encontrado: " + file.FullName, InfoMessage.Success_Message, 273, threadConfig.Name, ref appConfig);
                                        Document doc = new Document();
                                        doc.filePath = file.FullName;
                                        doc.length = file.Length;
                                        expedientes.Add(doc);
                                        message.sendMessage("Se agrego el archivo a lista el archivo: " + file.FullName, InfoMessage.Information_Message, 576, threadConfig.Name, ref appConfig);
                                    }

                                } break;
                            case 3:
                                {
                                    message.sendMessage("Buscando Archivos .DDF en la carpeta: " + dir.FullName, InfoMessage.Information_Message, 575, threadConfig.Name, ref appConfig);
                                    if (file.Extension.ToLower().Equals(".ddf"))
                                    {
                                        message.sendMessage("Archivo Encontrado: " + file.FullName, InfoMessage.Success_Message, 273, threadConfig.Name, ref appConfig);
                                        Document doc = new Document();
                                        doc.filePath = file.FullName;
                                        doc.length = file.Length;
                                        expedientes.Add(doc);
                                        message.sendMessage("Se agrego el archivo a lista el archivo: " + file.FullName, InfoMessage.Information_Message, 576, threadConfig.Name, ref appConfig);
                                    }

                                } break;
                            default:
                                throw new Exception("Tipo de archivo Invalido en la instanacia");
                            //throw new Exception("Tipo de Archivo Invalido");
                        }
                }
            }
            catch (IOException e)
            {
                throw new Exception("Error inesperado al intentar leer la carpeta y las subcarpetas: (" + threadConfig.DataPath + ")" + e.Message);
            }
            return expedientes;
        }


        public ArrayList getDataPreview2(ref Configuration appConfig, ref Thread_Config threadConfig)
        {
            ArrayList expedientes = new ArrayList();
            InfoMessage message = new InfoMessage();


            message.sendMessage("Iniciando la creacion del data previewList", InfoMessage.Information_Message, 573, threadConfig.Name, ref appConfig);
            message.sendMessage("Buscando archivos DATA en la carpeta: " + threadConfig.DataPath, InfoMessage.Information_Message, 574, threadConfig.Name, ref appConfig);
            try
            {

                foreach (String Path in System.IO.Directory.GetDirectories(threadConfig.DataPath))
                {
                    DirectoryInfo dir = new DirectoryInfo(Path);
                    foreach (FileInfo file in dir.GetFiles())//se buscan archivos de la misma carpeta
                        switch (threadConfig.Filetype)
                        {
                            case 1:
                                {
                                    message.sendMessage("Buscando Archivos .XML en la carpeta: " + dir.FullName, InfoMessage.Information_Message, 575, threadConfig.Name, ref appConfig);
                                    if (file.Extension.ToLower().Equals(".xml"))
                                    {
                                        message.sendMessage("Archivo Encontrado: " + file.FullName, InfoMessage.Success_Message, 273, threadConfig.Name, ref appConfig);
                                        Document doc = new Document();
                                        doc.filePath = file.FullName;
                                        doc.length = file.Length;
                                        expedientes.Add(doc);
                                        message.sendMessage("Se agrego el archivo a lista el archivo: " + file.FullName, InfoMessage.Information_Message, 576, threadConfig.Name, ref appConfig);
                                    }

                                } break;
                            //el csv no se podra combinar con este directoryOrganization
                            case 2:
                                {
                                    message.sendMessage("Buscando Archivos .CSV en la carpeta: " + dir.FullName, InfoMessage.Information_Message, 575, threadConfig.Name, ref appConfig);
                                    if (file.Extension.ToLower().Equals(".csv"))
                                    {
                                        message.sendMessage("Archivo Encontrado: " + file.FullName, InfoMessage.Success_Message, 273, threadConfig.Name, ref appConfig);
                                        Document doc = new Document();
                                        doc.filePath = file.FullName;
                                        doc.length = file.Length;
                                        expedientes.Add(doc);
                                        message.sendMessage("Se agrego el archivo a lista el archivo: " + file.FullName, InfoMessage.Information_Message, 576, threadConfig.Name, ref appConfig);
                                    }

                                } break;
                            case 3:
                                {
                                    message.sendMessage("Buscando Archivos .DDF en la carpeta: " + dir.FullName, InfoMessage.Information_Message, 575, threadConfig.Name, ref appConfig);
                                    if (file.Extension.ToLower().Equals(".ddf"))
                                    {
                                        message.sendMessage("Archivo Encontrado: " + file.FullName, InfoMessage.Success_Message, 273, threadConfig.Name, ref appConfig);
                                        Document doc = new Document();
                                        doc.filePath = file.FullName;
                                        doc.length = file.Length;
                                        expedientes.Add(doc);
                                        message.sendMessage("Se agrego el archivo a lista el archivo: " + file.FullName, InfoMessage.Information_Message, 576, threadConfig.Name, ref appConfig);
                                    }

                                } break;
                            default:
                                { throw new Exception("Tipo de archivo Invalido en la instanacia"); }
                            //throw new Exception("Organizacion de Directorios Invalida");
                        }
                }
            }
            catch (IOException e)
            {
                throw new Exception("Error inesperado al intentar leer la carpeta y las subcarpetas: (" + threadConfig.DataPath + ")" + e.Message);
            }
            return expedientes;
        }


        //Este metodo procesa los archivos con documents separados por carpetas
        //entonces cada carpeta a procesar es movida a una carpeta procesando

        public ArrayList getDataPreview3(ref Configuration appConfig, ref Thread_Config threadConfig)
        {
            ArrayList expedientes = new ArrayList();
            InfoMessage message = new InfoMessage();
            try
            {
                DirectoryInfo directory = new DirectoryInfo(threadConfig.DataPath); ;
                
                foreach (DirectoryInfo dir in directory.GetDirectories())
               
                    foreach (DirectoryInfo document in dir.GetDirectories())
                    
                        foreach (FileInfo file in document.GetFiles())                                                   
                                switch (threadConfig.Filetype)
                                {
                                    case 1:
                                        {
                                            message.sendMessage("Buscando Archivos .XML en la carpeta: " + document.FullName, InfoMessage.Information_Message, 575, threadConfig.Name, ref appConfig);
                                            if (file.Extension.ToLower().Equals(".xml"))
                                            {
                                                message.sendMessage("Archivo Encontrado: " + file.FullName, InfoMessage.Success_Message, 273, threadConfig.Name, ref appConfig);
                                                Document doc = new Document();
                                                doc.filePath = file.FullName;
                                                doc.length = file.Length;
                                                expedientes.Add(doc);
                                                message.sendMessage("Se agrego el archivo a lista el archivo: " + file.FullName, InfoMessage.Information_Message, 576, threadConfig.Name, ref appConfig);
                                            }
                                        } break;
                                    case 2:
                                        {
                                            message.sendMessage("Buscando Archivos .CSV en la carpeta: " + document.FullName, InfoMessage.Information_Message, 575, threadConfig.Name, ref appConfig);
                                            if (file.Extension.ToLower().Equals(".csv"))
                                            {
                                                message.sendMessage("Archivo Encontrado: " + file.FullName, InfoMessage.Success_Message, 273, threadConfig.Name, ref appConfig);
                                                String[] fileInfo = new String[2] { file.FullName, file.Length.ToString() };
                                                Document doc = new Document();
                                                doc.filePath = file.FullName;
                                                doc.length = file.Length;
                                                expedientes.Add(doc);
                                                message.sendMessage("Se agrego el archivo a lista el archivo: " + file.FullName, InfoMessage.Information_Message, 576, threadConfig.Name, ref appConfig);
                                            }
                                        } break;
                                    case 3:
                                        {
                                            message.sendMessage("Buscando Archivos .DDF en la carpeta: " + document.FullName, InfoMessage.Information_Message, 575, threadConfig.Name, ref appConfig);
                                            if (file.Extension.ToLower().Equals(".ddf"))
                                            {
                                                message.sendMessage("Archivo Encontrado: " + file.FullName, InfoMessage.Success_Message, 273, threadConfig.Name, ref appConfig);
                                                Document doc = new Document();
                                                doc.filePath = file.FullName;
                                                doc.length = file.Length;
                                                expedientes.Add(doc);
                                                message.sendMessage("Se agrego el archivo a lista el archivo: " + file.FullName, InfoMessage.Information_Message, 576, threadConfig.Name, ref appConfig);
                                            }
                                        } break;
                                    default:
                                        { throw new Exception("Tipo de archivo Invalido en la instanacia"); }
                                
                            
                        
                    
                }
                return expedientes;
            }
            catch (IOException e)
            {
                throw new Exception("Error inesperado al intentar leer la carpeta y las subcarpetas: (" + threadConfig.DataPath + ")" + e.Message);
            }
        }
        #endregion


        //crean todos los documents
        #region Procesar Archivos

        public MailMessage procesarXML(Document previewDocument,ref Configuration appConfig, ref Thread_Config threadConfig)
        {
            MailMessage result = new MailMessage();
            InfoMessage message = new InfoMessage();
            message.sendMessage("Procesando archivo: " + previewDocument.filePath, InfoMessage.Information_Message, 547, threadConfig.Name,ref appConfig);
            previewDocument.filePath = cambiandoExtension(previewDocument.filePath, ".umi",ref appConfig, ref threadConfig);
            try
            {
                FileInfo infoFile = new FileInfo(previewDocument.filePath);
                if (infoFile.Exists)
                {
                    if (infoFile.Length == Convert.ToInt32(previewDocument.length))
                    {
                        message.sendMessage("Bloqueando Archivo: " + previewDocument.filePath, InfoMessage.Information_Message, 577, threadConfig.Name, ref appConfig);
                        StreamReader sr = new StreamReader(previewDocument.filePath);//bloquea el archivo para escritura mientras se lee el archivo
                        message.sendMessage("Archivo Bloqueado: " + previewDocument.filePath, InfoMessage.Success_Message, 274, threadConfig.Name, ref appConfig);
                        XmlDocument xDoc = new XmlDocument();
                        xDoc.Load(previewDocument.filePath);
                        message.sendMessage("Archivo Cargado: " + previewDocument.filePath + " correctamente", InfoMessage.Success_Message, 275, threadConfig.Name, ref appConfig);
                        // Archivo cargado correctamente.

                        XmlNodeList configuraciones = xDoc.GetElementsByTagName("DOCUMENTOS");
                        XmlNodeList lista = ((XmlElement)configuraciones[0]).GetElementsByTagName("DOCUMENTO");
                        message.sendMessage("Buscando documentos del archivo: " + previewDocument.filePath, InfoMessage.Information_Message, 578, threadConfig.Name, ref appConfig);
                        ArrayList documentos = new ArrayList();
                        /*
                         * Almacena cada campo de indexacion con su respectivo valor.
                        */
                        int numeracionDocumental = 0;
                        foreach (XmlElement nodo in lista)
                        {
                            message.sendMessage("Procesando nodo " + numeracionDocumental + " (documento) del archivo: " + previewDocument.filePath, InfoMessage.Information_Message, 579, threadConfig.Name, ref appConfig);
                            Document document = new Document();
                            for (int i = 0; i < nodo.ChildNodes.Count; i++)
                            {
                                if (nodo.ChildNodes.Item(i).Name.Equals("IMAGENES"))
                                {
                                    message.sendMessage("Procesando nodo IMAGENES del archivo: " + previewDocument.filePath, InfoMessage.Information_Message, 580, threadConfig.Name, ref appConfig);
                                    XmlNodeList nodoHijo = nodo.GetElementsByTagName("IMAGEN");
                                    foreach (XmlElement imagen in nodoHijo)
                                    {
                                        message.sendMessage("Nodo Encontrado con nombre: IMAGEN y valor: " + imagen.InnerText + " del archivo: " + previewDocument.filePath, InfoMessage.Information_Message, 581, threadConfig.Name, ref appConfig);
                                        IndexField index = new IndexField();
                                        index.name="IMAGEN";
                                        index.value=imagen.InnerText;
                                        document.indexFields.Add(index);
                                    }
                                }
                                else
                                {


                                    if ((nodo.ChildNodes.Item(i).Name.Equals("UNIDADDOCUMENTAL")) || (nodo.ChildNodes.Item(i).Name.Equals("UNI_DOCUMENTAL")) || (nodo.ChildNodes.Item(i).Name.Equals("UNI_DOC")))
                                    {
                                        document.docUnit = nodo.ChildNodes.Item(i).InnerText;
                                        message.sendMessage("Unidad Documental Encontrada con nombre: " + nodo.ChildNodes.Item(i).Name + " y valor: " + nodo.ChildNodes.Item(i).InnerText + " del archivo: " + previewDocument.filePath, InfoMessage.Information_Message, 581, threadConfig.Name, ref appConfig);
                                    }
                                    else

                                        if ((nodo.ChildNodes.Item(i).Name.Equals("CLASEDOCUMENTAL")) || (nodo.ChildNodes.Item(i).Name.Equals("OBJECT_CLASS")))
                                        {
                                            document.docClass = nodo.ChildNodes.Item(i).InnerText;
                                            message.sendMessage("Clase Documental Encontrada con nombre: " + nodo.ChildNodes.Item(i).Name + " y valor: " + nodo.ChildNodes.Item(i).InnerText + " del archivo: " + previewDocument.filePath, InfoMessage.Information_Message, 581, threadConfig.Name, ref appConfig);
                                        }
                                        else
                                        {
                                            message.sendMessage("Campo de Indexacion Encontrado con nombre: " + nodo.ChildNodes.Item(i).Name + " y valor: " + nodo.ChildNodes.Item(i).InnerText + " del archivo: " + previewDocument.filePath, InfoMessage.Information_Message, 581, threadConfig.Name, ref appConfig);
                                            IndexField index = new IndexField();
                                            index.name = nodo.ChildNodes.Item(i).Name;
                                            index.value = nodo.ChildNodes.Item(i).InnerText;
                                            document.indexFields.Add(index);
                                        }
                                }
                            }

                            document.docName=infoFile.Name.Split('.')[0] + "_" + numeracionDocumental.ToString();
                            message.sendMessage("Documento:" + document.docName + " creado del archivo: " + previewDocument.filePath, InfoMessage.Success_Message, 276, threadConfig.Name, ref appConfig);
                            numeracionDocumental++;

                            document.filePath = previewDocument.filePath;                           
                            //validar campos requeridos

                            if (camposRequeridos(document, ref appConfig, ref threadConfig))
                            {
                                documentos.Add(document);
                                
                                if (documentos.Count == threadConfig.MaxFiles)
                                {
                                    UpDocuments upDocs = new UpDocuments();
                                    upDocs.process(documentos,ref appConfig,ref threadConfig);
                                    documentos = new ArrayList();
                                    message.sendMessage("Bloque Subido con exito ", InfoMessage.Success_Message, 289, threadConfig.Name, ref appConfig);  
                                    continue;
                                }
                            }
                            else
                            {
                                FileMessage fMessage = new FileMessage("El documento: " + document.docName + " no contiene todos los campos requeridos", new Exception("El documento esta mal indexado: " + previewDocument.docName), previewDocument.filePath, 113, threadConfig.Name);
                                fMessage.sendMessage(ref appConfig);
                                result.documentsNoOk++;
                                continue;
                            }
                        }
                        sr.Close();
                        message.sendMessage("Archivo Desbloqueado: " + previewDocument.filePath, InfoMessage.Success_Message, 277, threadConfig.Name, ref appConfig);
                        message.sendMessage("Archivo Procesado con exito: " + previewDocument.filePath, InfoMessage.Success_Message, 278, threadConfig.Name, ref appConfig);                      
                        
                        if (documentos.Count > 0)
                        {
                            //subir documentos faltantes
                            UpDocuments upDocs = new UpDocuments();
                            MailMessage parcial = upDocs.process(documentos, ref appConfig, ref threadConfig);
                            documentos = new ArrayList();
                            result.documentsOk += parcial.documentsOk;
                            result.documentsNoOk += parcial.documentsNoOk;
                            message.sendMessage("Bloque Subido con exito ", InfoMessage.Success_Message, 289, threadConfig.Name, ref appConfig);  
                        }
                        
                        return result;

                    }
                    else
                    {
                        FileMessage fMessage = new FileMessage("El archivo: " + previewDocument.filePath + " no fue procesado por incompatibilidad de tamaño en el proceso. Tamaño original: " + previewDocument.length + "Tamaño Actual: " + infoFile.Length.ToString(), new Exception("El archivo " + previewDocument.filePath + " no tuvo compatibilidad de tamaños en el proceso. Archivo omitido"), previewDocument.filePath, 109, threadConfig.Name);
                        fMessage.sendMessage(ref appConfig);
                        return result;
                    }
                }
                else
                {
                    FileMessage fMessage = new FileMessage("El archivo: " + previewDocument.filePath + " no existe", new Exception("Archivo: " + previewDocument.filePath + "no existe"), previewDocument.filePath, 108, threadConfig.Name);
                    fMessage.sendMessage(ref appConfig);
                    return result;
                }
            }
            catch (Exception exc)
            {
                FileMessage fMessage = new FileMessage("Error Inesperado al procesar el documento: "+previewDocument.filePath, exc, previewDocument.filePath, 110, threadConfig.Name);
                fMessage.sendMessage(ref appConfig);
                return result;
            }

        }

        public MailMessage procesarCSV(Document previewDocument, ref Configuration appConfig, ref Thread_Config threadConfig)
        {            
            ArrayList documentos = new ArrayList();
            MailMessage result = new MailMessage();
            InfoMessage message = new InfoMessage();
            previewDocument.filePath = cambiandoExtension(previewDocument.filePath, ".umi", ref appConfig, ref threadConfig);
            FileInfo infoFile = new FileInfo(previewDocument.filePath);
            if (infoFile.Exists)
            {
                if (infoFile.Length == Convert.ToInt32(previewDocument.length))
                {
                    try
                    {
                        message.sendMessage("Bloqueando Archivo: " + previewDocument.filePath, InfoMessage.Information_Message, 577, threadConfig.Name, ref appConfig);
                        StreamReader reader = new StreamReader(previewDocument.filePath);
                        message.sendMessage("Archivo Bloqueado: " + previewDocument.filePath, InfoMessage.Success_Message, 274, threadConfig.Name, ref appConfig);
                        string line;

                        Document documento = new Document();
                        while ((line = reader.ReadLine()) != null)
                        {
                            message.sendMessage("Procesando DOCUMENTO del archivo: " + previewDocument.filePath, InfoMessage.Information_Message, 579, threadConfig.Name, ref appConfig);
                            String[] datos = line.Split(',');
                            message.sendMessage("Dato de indexacion encontrado: " + datos[0].Substring(1, datos[0].Length - 2) + ": " + datos[1].Substring(1, datos[1].Length - 2) + " del archivo: " + previewDocument.filePath, InfoMessage.Information_Message, 581, threadConfig.Name, ref appConfig);                                

                            IndexField index = new IndexField();
                            index.name=datos[0].Substring(1, datos[0].Length - 2);
                            index.value=datos[1].Substring(1, datos[1].Length - 2);

                            if ((index.name.Equals("OBJECT_CLASS")) || (index.name.Equals("CLASEDOCUMENTAL")))
                                documento.docClass=index.value;
                            else
                                if ((index.name.Equals("UNI_DOCUMENTAL")) || (index.name.Equals("UNI_DOC")))
                                    documento.docUnit=index.value; 
                                else
                                    documento.indexFields.Add(index);
                        }
                            
                        documento.docName= infoFile.Name.Split('.')[0] ;
                        message.sendMessage("Dato de indexacion encontrado: " + "docName" + ": " + documento.docName + " del archivo: " + previewDocument.filePath, InfoMessage.Information_Message, 581, threadConfig.Name, ref appConfig);
                        
                        documento.filePath = previewDocument.filePath;

                        if (camposRequeridos(documento, ref appConfig, ref threadConfig))
                        {                          
                            documentos.Add(documento);

                            UpDocuments upDocs = new UpDocuments();
                            upDocs.process(documentos, ref appConfig, ref threadConfig);
                            documentos = new ArrayList();
                            message.sendMessage("Bloque subido con exito ", InfoMessage.Success_Message, 289, threadConfig.Name, ref appConfig);  
                            //en subir documentos se deben buscar las imagenes
                            //subir documento
                        }
                        else
                        {
                           FileMessage fMessage = new FileMessage("El documento: " + documento.docName + " no contiene todos los campos requeridos", new Exception("El documento esta mal indexado: " + previewDocument.docName), previewDocument.filePath, 113, threadConfig.Name);
                           fMessage.sendMessage(ref appConfig);
                           result.documentsNoOk++;
                        }
                        
                        reader.Close();
                        message.sendMessage("Archivo Desbloqueado: " + previewDocument.filePath, InfoMessage.Success_Message, 277, threadConfig.Name, ref appConfig);
                        message.sendMessage("Archivo Procesado con exito: " + previewDocument.filePath, InfoMessage.Success_Message, 278, threadConfig.Name, ref appConfig);
                        return result;
                    }
                    catch (Exception e) 
                    {
                        FileMessage fMessage = new FileMessage("Error Inesperado al procesar el documento: " + previewDocument.filePath, e, previewDocument.filePath, 110, threadConfig.Name);
                        fMessage.sendMessage( ref appConfig);
                        return result;
                    }
                }
                else
                {
                    FileMessage fMessage = new FileMessage("El archivo: " + previewDocument.filePath + " no fue procesado por incompatibilidad de tamaño en el proceso. Tamaño original: " + previewDocument.length + "Tamaño Actual: " + infoFile.Length.ToString(), new Exception("El archivo " + previewDocument.filePath + " no tuvo compatibilidad de tamaños en el proceso. Archivo omitido"), previewDocument.filePath, 109, threadConfig.Name);
                    fMessage.sendMessage(ref appConfig);
                    return result;
                }
            }
            else
            {
                FileMessage fMessage = new FileMessage("El archivo: " + previewDocument.filePath + " no existe", new Exception("Archivo: " + previewDocument.filePath + "no existe"), previewDocument.filePath, 108, threadConfig.Name);
                fMessage.sendMessage( ref appConfig);
                return result;
            }
            
        }


        public MailMessage procesarPLANO(Document previewDocument, ref Configuration appConfig, ref Thread_Config threadConfig)
        {
            MailMessage result = new MailMessage();
            InfoMessage message = new InfoMessage();
            message.sendMessage("Procesando archivo: " + previewDocument.filePath, InfoMessage.Information_Message, 547, threadConfig.Name,ref appConfig);
            previewDocument.filePath = cambiandoExtension(previewDocument.filePath, ".umi", ref appConfig, ref threadConfig);
            FileInfo infoFile = new FileInfo(previewDocument.filePath);
            ArrayList documentos = new ArrayList();
            if (infoFile.Exists)
            {
                if (infoFile.Length == Convert.ToInt32(previewDocument.length))
                {
                    try
                    {

                        message.sendMessage("Bloqueando Archivo: " + previewDocument.filePath, InfoMessage.Information_Message, 577, threadConfig.Name, ref appConfig);
                        StreamReader sr = new StreamReader(previewDocument.filePath);
                        message.sendMessage("Archivo Bloqueado: " + previewDocument.filePath, InfoMessage.Success_Message, 274, threadConfig.Name, ref appConfig);
                        String line = "";
                        while ((line = sr.ReadLine()) != null)
                        {
                            if (line.Equals("DOCUMENT"))
                            {
                                message.sendMessage("Procesando DOCUMENTO del archivo: " + previewDocument.filePath, InfoMessage.Information_Message, 579, threadConfig.Name, ref appConfig);
                                Document documento = new Document();
                                String[] datos = line.Split('|');
                                while (!(datos[0]).Equals(""))
                                {
                                    switch (datos[0].ToUpper())
                                    {
                                        case "DOCFIELD":
                                            {
                                                if (datos[1].Equals("UNI_DOC"))
                                                {
                                                    documento.docUnit = datos[2];
                                                    message.sendMessage("Unidad Documental encontrada: " + datos[2] + " del archivo: " + previewDocument.filePath, InfoMessage.Information_Message, 581, threadConfig.Name, ref appConfig);
                                                }
                                                else
                                                {
                                                    if (!(datos[1].Equals("%DomainName")))
                                                    {
                                                        IndexField index = new IndexField();
                                                        index.name = datos[1];
                                                        index.value = datos[2];
                                                        documento.indexFields.Add(index);
                                                        message.sendMessage("Dato de indexacion encontrado: " + datos[1] + ": " + datos[2] + " del archivo: " + previewDocument.filePath, InfoMessage.Information_Message, 581, threadConfig.Name, ref appConfig);
                                                    }
                                                }
                                            } break;
                                        case "PAGE":
                                            {
                                                IndexField index = new IndexField();
                                                index.name="IMAGEN";
                                                index.value=datos[2];
                                                documento.indexFields.Add(index);
                                                message.sendMessage("Nombre de la imagen asociada encontrada: IMAGEN: " + datos[2] + " del archivo: " + previewDocument.filePath, InfoMessage.Information_Message, 581, threadConfig.Name, ref appConfig);
                                            } break;
                                        case "DOCNAME":
                                            {
                                                documento.docName = datos[1];
                                                message.sendMessage("Nombre de documento encontrado: " + datos[0] + ": " + datos[1] + " del archivo: " + previewDocument.filePath, InfoMessage.Information_Message, 581, threadConfig.Name, ref appConfig);
                                            } break;
                                        case "CLASS":
                                            {
                                                documento.docClass = datos[1];
                                                message.sendMessage("Clase Documental encontrada: " + datos[1] + " del archivo: " + previewDocument.filePath, InfoMessage.Information_Message, 581, threadConfig.Name, ref appConfig);
                                            }break;
                                        default:
                                            {
                                                message.sendMessage("Linea Ignorada por no proporcionar informacion valiosa (" + line + ")" + " del archivo: " + previewDocument.filePath, InfoMessage.Information_Message, 582, threadConfig.Name, ref appConfig);
                                            } break;
                                    }
                                    line = sr.ReadLine();
                                    datos = line.Split('|');
                                }
                                message.sendMessage("Documento:" + documento.docName + " creado del archivo: " + previewDocument.filePath, InfoMessage.Success_Message, 276, threadConfig.Name, ref appConfig);

                                documento.filePath = previewDocument.filePath;

                                if (camposRequeridos(documento,ref appConfig,ref threadConfig))
                                {
                                    documentos.Add(documento);
                                    if (documentos.Count == threadConfig.MaxFiles)
                                    {
                                        UpDocuments upDocs = new UpDocuments();
                                        upDocs.process(documentos, ref appConfig, ref threadConfig);
                                        documentos = new ArrayList();
                                        message.sendMessage("Bloque Subido con exito ", InfoMessage.Success_Message, 289, threadConfig.Name,ref appConfig);  
                                        continue;
                                    }
                                }
                                else
                                {
                                    FileMessage fMessage = new FileMessage("El documento: " + documento.docName + " no contiene todos los campos requeridos", new Exception("El documento esta mal indexado: " + previewDocument.docName), previewDocument.filePath, 113, threadConfig.Name);
                                    fMessage.sendMessage(ref appConfig);
                                    result.documentsNoOk++;
                                    continue;
                                }
                            }
                        }
                        sr.Close();
                        message.sendMessage("Archivo Desbloqueado: " + previewDocument.filePath, InfoMessage.Success_Message, 277, threadConfig.Name,ref appConfig);
                        message.sendMessage("Archivo Procesado con exito: " + previewDocument.filePath, InfoMessage.Success_Message, 278, threadConfig.Name,ref appConfig);
                        if (documentos.Count > 0)
                        {
                            //subir documentos faltantes
                            UpDocuments upDocs = new UpDocuments();
                            upDocs.process(documentos, ref appConfig, ref threadConfig);
                            documentos = new ArrayList();
                            message.sendMessage("Bloque Subido con exito ", InfoMessage.Success_Message, 289, threadConfig.Name,ref appConfig);  
                        }
                        return result;
                    }
                    catch (Exception e)
                    {
                        FileMessage fMessage = new FileMessage("Error Inesperado al procesar el documento: " + previewDocument.filePath, e, previewDocument.filePath, 110, threadConfig.Name);
                        fMessage.sendMessage(ref appConfig);
                        return result;
                    }
                }
                else
                {
                    FileMessage fMessage = new FileMessage("El archivo: " + previewDocument.filePath + " no fue procesado por incompatibilidad de tamaño en el proceso. Tamaño original: " + previewDocument.length + "Tamaño Actual: " + infoFile.Length.ToString(), new Exception("El archivo " + previewDocument.filePath + " no tuvo compatibilidad de tamaños en el proceso. Archivo omitido"), previewDocument.filePath, 109, threadConfig.Name);
                    fMessage.sendMessage(ref appConfig);
                    return result;
                }
            }
            else
            {
                FileMessage fMessage = new FileMessage("El archivo: " + previewDocument.filePath + " no existe", new Exception("Archivo: " + previewDocument.filePath + "no existe"), previewDocument.filePath, 108, threadConfig.Name);
                fMessage.sendMessage(ref appConfig);
                return result;
            }
        }


        #endregion

        //valida que los campos requeridos se encuentren seteados en cada documento
        #region Validacion Campos Requeridos

        /// <summary>
        /// Método para validar campos requeridos
        /// </summary>
        /// <param name="XML_Path">Ruta donde se hospeda el XML </param>
        /// <param name="claseDocumental">Clase Documental a buscar.</param>
        /// <param name="unidadDocumental">Unidad Documental a buscar.</param>
        /// <returns></returns>
        private ArrayList LecturaCamposRequeridos(string XML_Path, string claseDocumental, string unidadDocumental, ref Configuration appConfig, ref Thread_Config threadConfig)
        {
            InfoMessage message = new InfoMessage();
            try
            {
                XmlDocument xDoc = new XmlDocument();
                message.sendMessage("Leyendo archivo con politicas de campos requeridos en la ruta [" + XML_Path + "].", InfoMessage.Information_Message, 623, threadConfig.Name, ref appConfig);
                xDoc.Load(XML_Path);
                message.sendMessage("Archivo [" + XML_Path + "] leído satisfactoriamente.", InfoMessage.Success_Message, 287, threadConfig.Name, ref appConfig);
                XmlNodeList personas = xDoc.GetElementsByTagName("CLASESDOCUMENTALES");

                XmlNodeList lista =
                ((XmlElement)personas[0]).GetElementsByTagName("CLASEDOCUMENTAL");

                foreach (XmlElement nodo in lista)
                {
                    string nNombre = nodo.GetAttribute("name");
                    string nombre = "";
                    string msg = "";

                    if (nNombre.ToUpper().Equals(claseDocumental.ToUpper()))
                    {
                        XmlNodeList nodoHijo = nodo.GetElementsByTagName("UNIDADDOCUMENTAL");

                        foreach (XmlElement unidad_Doc in nodoHijo)
                        {
                            nombre = unidad_Doc.GetAttribute("name");

                            if (nombre.ToUpper().Equals(unidadDocumental.ToUpper()))
                            {
                                ArrayList nuevo = new ArrayList();
                                XmlNodeList campos = unidad_Doc.GetElementsByTagName("CAMPO");
                                foreach (XmlElement campo in campos)
                                {
                                    IndexRequiredField datos = new IndexRequiredField();
                                    datos.name = campo.GetAttribute("FileName");
                                    datos.IIF_FieldName = campo.InnerText;
                                    datos.required = Boolean.Parse(campo.GetAttribute("Required"));
                                    
                                    nuevo.Add(datos);
                                    msg += "\n"+campo.InnerText+"["+campo.GetAttribute("FileName")+"] Requerido="+datos.required+" , ";
                                }
                                return nuevo;
                            }
                        }

                    } // end if
                    message.sendMessage("Campos encontrados para Clase Documental [" + nNombre + " ], Unidad Documental [" + nombre + "]:" + msg, InfoMessage.Information_Message, 624, threadConfig.Name, ref appConfig);

                }
                throw new Exception("Error de formato del arhivo (politicas de campos requeridos)");
            }
            catch (Exception exc)
            {
                FileMessage fMessage=new FileMessage("Error en la lectura del archivo de campos requeridos.", exc,XML_Path,114,threadConfig.Name);
                fMessage.sendMessage(ref appConfig);

                return null;
            }



        }

        /// <summary>
        /// Método para la validación de los campos requeridos.
        /// </summary>
        /// <param name="document"></param>
        /// <returns></returns>
        private bool camposRequeridos(Document document, ref Configuration appConfig, ref Thread_Config threadConfig)
        {
            
            InfoMessage message = new InfoMessage();
            message.sendMessage("Verificando Campos Requeridos....", InfoMessage.Information_Message, 625, threadConfig.Name, ref appConfig);
        
            try
            {
                if ((document.docUnit.Equals("")) || (document.docName.Equals("")) || (document.docClass.Equals("")))
                {
                    FileMessage fMessage = new FileMessage("El documento no contiene todos los campos requeridos ", new Exception("Clase Documental,Nombre Documento o Unidad Documental no encontrada"), document.filePath, 113, threadConfig.Name);
                    fMessage.sendMessage( ref appConfig);
                    return false;
                }

            }
            catch (Exception e)
            {
                FileMessage fMessage = new FileMessage("El documento no contiene todos los campos requeridos ", new Exception("Clase Documental,Nombre Documento o Unidad Documental no encontrada"), document.filePath, 113,threadConfig.Name);
                fMessage.sendMessage( ref appConfig);
                return false;
            }
            string file = "";

            try
            {
                message.sendMessage("Intentando leer el archivo: " + threadConfig.required_fields, InfoMessage.Information_Message, 503, threadConfig.Name, ref appConfig);
                file = threadConfig.required_fields;

            }
            catch (Exception e)
            {
                FileMessage fMessage = new FileMessage("Error al leer el archivo de campos requeridos ", e, document.filePath, 113,  threadConfig.Name);
                fMessage.sendMessage( ref appConfig);
                return false;
            }

            ArrayList campos = new ArrayList();
            if (File.Exists(file))
                campos = LecturaCamposRequeridos(file, document.docClass, document.docUnit,ref appConfig,ref threadConfig);
            else
            {
                FileMessage fMessage = new FileMessage("El archivo: " + file + " no existe", new Exception("El archivo no fue encontrado"), file, 113, threadConfig.Name);
                fMessage.sendMessage( ref appConfig);
                return false;
            }

            if (campos.Count==0)
                return false;

            for (int i = 0; i < campos.Count; i++)
            {
                bool band = false;
                for (int j = 0; j < document.indexFields.Count; j++)
                {
                    IndexField indexField = (IndexField)document.indexFields[j];
                    IndexRequiredField campo = (IndexRequiredField)campos[i];
                    //String[] campo=((String[])campos[i]);
                    if (indexField.name.Equals(campo.name))//en esta version se elimina el toLower() por correo del 13 marzo 2013
                    {
                        if ((indexField.value.Equals(""))&&(campo.required))
                        {
                            FileMessage fMessage = new FileMessage("El documento no contiene todos los campos requeridos", new Exception("El campo: " + indexField.name + " esta vacio"), file, 113, threadConfig.Name);
                            fMessage.sendMessage( ref appConfig);
                            return false;
                        }
                        else
                        {
                            message.sendMessage("Campo Encontrado: " + indexField.name + "[" + indexField.value + "], nombre en IIF = " + campo.IIF_FieldName, InfoMessage.Information_Message, 626, threadConfig.Name, ref appConfig);
                            band = true;
                            indexField.name = campo.IIF_FieldName;
                            break;
                        }                        
                    }
                }
                if (!(band))
                {
                    FileMessage fMessage =new FileMessage("El documento no contiene todos los campos requeridos ", new Exception("El campo: " + campos[i] + " no existe"), document.filePath, 113, threadConfig.Name);
                    fMessage.sendMessage( ref appConfig);
                    return false;
                }
            }

            message.sendMessage("Fin de Verificando Campos Requeridos....", InfoMessage.Information_Message, 627, threadConfig.Name, ref appConfig);
            return true;
        }

        #endregion

        //genera la lista de imagenes del documento
        #region Obtener Imagenes


        public String getImages1(String ImageName, ref Configuration appConfig, ref Thread_Config threadConfig)
        {
            InfoMessage message = new InfoMessage();
            message.sendMessage("Buscando Imagen: " + ImageName + " en File System", InfoMessage.Information_Message, 584, threadConfig.Name, ref appConfig);
            try
            {
                foreach (String dayPath in System.IO.Directory.GetDirectories(threadConfig.ImagesPath))
                {
                    DirectoryInfo dir = new DirectoryInfo(dayPath + "\\Images");
                    foreach (FileInfo file in dir.GetFiles())//se buscan archivos dentro de la carpeta images    
                    {
                        message.sendMessage("Buscando Imagen: " + ImageName + " en la carpeta: " + dir, InfoMessage.Information_Message, 574, threadConfig.Name, ref appConfig);
                        if ((file.Extension.ToLower().Equals(".tif")) || (file.Extension.ToLower().Equals(".pdf")) || (file.Extension.ToLower().Equals(".tiff")))
                        {
                            message.sendMessage("Comparando: " + file.Name.Split('.')[0].ToLower() + " con: " + ImageName.ToLower(), InfoMessage.Information_Message, 585, threadConfig.Name, ref appConfig);
                            if (file.Name.Split('.')[0].ToLower().Equals(ImageName.ToLower()))
                            {
                                cambiandoExtension(file.FullName, ".umi", ref appConfig, ref threadConfig);
                                message.sendMessage("Imagen encontrada: " + file.FullName, InfoMessage.Success_Message, 273, threadConfig.Name, ref appConfig);
                                message.sendMessage("Se agrego el archivo a lista el archivo: " + file.FullName, InfoMessage.Information_Message, 576, threadConfig.Name, ref appConfig);
                                return file.FullName + ".umi";
                            }
                            else
                                message.sendMessage("Archivo: " + file.FullName + " descartado.", InfoMessage.Information_Message, 585, threadConfig.Name, ref appConfig);
                        }
                        else
                            message.sendMessage("Archivo: " + file.FullName + " descartado.", InfoMessage.Information_Message, 585, threadConfig.Name, ref appConfig);
                    }
                }
                throw new Exception("La imagen " + ImageName + " no fue encontrada, revise la configuracion");
            }
            catch (Exception e)
            {
                throw new Exception("Error Inesperado: " + e.Message);
            }
        }

        public String getImages2(String ImageName, ref Configuration appConfig, ref Thread_Config threadConfig)
        {
            InfoMessage message = new InfoMessage();
            message.sendMessage("Buscando Imagen: " + ImageName + " en File System", InfoMessage.Information_Message, 584, threadConfig.Name, ref appConfig);
            ArrayList expedientes = new ArrayList();
            try
            {
                foreach (String Path in System.IO.Directory.GetDirectories(threadConfig.ImagesPath))
                {
                    DirectoryInfo dir = new DirectoryInfo(Path);
                    foreach (FileInfo file in dir.GetFiles())//se buscan archivos de la misma carpeta
                    {
                        message.sendMessage("Buscando Imagen: " + ImageName + " en la carpeta: " + dir, InfoMessage.Information_Message, 574, threadConfig.Name, ref appConfig);
                        if ((file.Extension.ToLower().Equals(".tif")) || (file.Extension.ToLower().Equals(".pdf")) || (file.Extension.ToLower().Equals(".tiff")))
                        {
                            message.sendMessage("Comparando: " + file.Name.Split('.')[0].ToLower() + " con: " + ImageName.ToLower(), InfoMessage.Information_Message, 585, threadConfig.Name, ref appConfig);
                            if (file.Name.Split('.')[0].ToLower().Equals(ImageName.ToLower()))
                            {
                                cambiandoExtension(file.FullName, ".umi", ref appConfig, ref threadConfig);
                                message.sendMessage("Imagen encontrada: " + file.FullName, InfoMessage.Success_Message, 273, threadConfig.Name,ref appConfig);
                                message.sendMessage("Se agrego el archivo a lista el archivo: " + file.FullName, InfoMessage.Information_Message, 576, threadConfig.Name, ref appConfig);
                                return file.FullName + ".umi";
                            }
                            else
                                message.sendMessage("Archivo: " + file.FullName + " descartado.", InfoMessage.Information_Message, 585, threadConfig.Name, ref appConfig);
                        }
                        else
                            message.sendMessage("Archivo: " + file.FullName + " descartado.", InfoMessage.Information_Message, 585, threadConfig.Name, ref appConfig);

                    }
                }
                throw new Exception("La imagen " + ImageName + " no fue encontrada.");
            }
            catch (IOException e)
            {
                throw new Exception("Error Inesperado: " + e.Message);
            }
        }

        public ArrayList getImages3(Document document,ref Configuration appConfig, ref Thread_Config threadConfig)
        {
            InfoMessage message = new InfoMessage();
            ArrayList images = new ArrayList();
            try
            {
                DirectoryInfo directory = new DirectoryInfo(new System.IO.FileInfo(document.filePath).DirectoryName); ;

                
            foreach (FileInfo file in directory.GetFiles())
                {
                    
                    if ((file.Extension.ToLower().Equals(".tif")) || (file.Extension.ToLower().Equals(".pdf")) || (file.Extension.ToLower().Equals(".tiff")))
                    {

                        message.sendMessage("Imagen encontrada: " + file.FullName, InfoMessage.Success_Message, 273, threadConfig.Name, ref appConfig);
                        message.sendMessage("Se agrego el archivo a lista el archivo: " + file.FullName, InfoMessage.Information_Message, 576, threadConfig.Name, ref appConfig);
                        cambiandoExtension(file.FullName, ".umi", ref appConfig, ref threadConfig);
                        Images image = new Images();
                        image.name = file.Name.Split('.')[0];
                        image.path = file.FullName+".umi";
                        images.Add(image);
                    }
                    else
                        message.sendMessage("Archivo: " + file.FullName + " descartado.", InfoMessage.Information_Message, 585, threadConfig.Name, ref appConfig);
                }
            return images;
            }
            catch (IOException e)
            {
                throw new Exception("Error Inesperado: " + e.Message);
            }
        }
        #endregion

        //generacion de historico
        #region Manipulacion Archivos
        //origen: archivo o carpeta que se desea mover
        //destino: carpeta en donde se movera
        public void Move(String Origin, String Destiny,ref Configuration appConfig,ref Thread_Config threadConfig)
        {

            try
            {
                
                InfoMessage message = new InfoMessage();
                if (Directory.Exists(Origin))
                {
                    message.sendMessage("Intentando mover: " + Origin + " a: " + Destiny, InfoMessage.Success_Message, 269, threadConfig.Name, ref appConfig);
                    Directory.Move(Origin, Destiny);
                    message.sendMessage("Carpeta: " + Origin + "  ha sido movida a: " + Destiny, InfoMessage.Success_Message, 269, threadConfig.Name, ref appConfig);
                    return;
                }
                if (File.Exists(Origin))
                {
                    message.sendMessage("Intentando mover: " + Origin + " a: " + Destiny + "\\" + new FileInfo(Origin).Name, InfoMessage.Success_Message, 269, threadConfig.Name, ref appConfig);
                    File.Move(Origin, Destiny + "\\" + new FileInfo(Origin).Name);
                    message.sendMessage("Archivo: " + Origin + "  ha sido movido a: " + Destiny, InfoMessage.Success_Message, 269, threadConfig.Name, ref appConfig);
                    return;
                }
            }
            catch (Exception e)
            {
                throw new Exception("Imposible mover : " + Origin + " hacia: " + Destiny + "\n Los datos seran reprocesados en la proxima ejecucion del thread si no son movidos (" + e.Message + ")");
            }
        }

        public void Delete(String directory, ref Configuration appConfig, ref Thread_Config threadConfig)
        {

            try
            {
                InfoMessage message = new InfoMessage();
                if (Directory.Exists(directory))
                {
                    Directory.Delete(directory);
                    message.sendMessage("Carpeta: " + directory + "  ha sido borrada de File System", InfoMessage.Success_Message, 270, threadConfig.Name,ref appConfig);
                    return;
                }
                if (File.Exists(directory))
                {
                    File.Delete(directory);
                    message.sendMessage("Archivo: " + directory + "  ha sido borrada de File System", InfoMessage.Success_Message, 270, threadConfig.Name, ref appConfig);
                    return;
                }
            }
            catch (Exception e)
            {
                throw new Exception("Imposible eliminar : " + directory + " del File System" + "\n Los datos seran reprocesados en la proxima ejecucion del thread si no son movidos (" + e.Message + ")");
            }
        }



        public String cambiandoExtension(String file, String ext, ref Configuration appConfig, ref Thread_Config threadConfig)
        {
            try
            {
                InfoMessage message = new InfoMessage();
                message.sendMessage("Intentando cambiar la extension al archivo: " + file, InfoMessage.Information_Message, 543, threadConfig.Name, ref appConfig);
                System.IO.File.Move(file, file + ext);
                message.sendMessage("Archivo: " + file + " modificado a: " + file + ext, InfoMessage.Success_Message, 266, threadConfig.Name, ref appConfig);
                return new FileInfo(file + ext).FullName;
                
            }
            catch (Exception ex)
            {
                FileMessage fMessage = new FileMessage("Imposible cambiar la extension de archivo: " + file , ex, file, 102, threadConfig.Name);
                fMessage.sendMessage( ref appConfig);
                return file;
            }
        }

        
        #endregion
    }
}
